/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.braveo.dict.javadoc;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author jeff.huang
 */
public class DocHelper {
    private Logger logger = Logger.getLogger(DocHelper.class.getName());
    private final String clazzName;
    private final String clazzFullName;
    private List<String> clazzInfo = new LinkedList<String>();
    private Map<String, List<String>> detailInfo = new HashMap<String, List<String>>();

    private String currentDetailKey = null;
    private int stage = 0;

    private static final String CONST_SUMMARY = "<!-- ======== CONSTRUCTOR SUMMARY ======== -->";
    private static final String FIELD_SUMMARY = "<!-- =========== FIELD SUMMARY =========== -->";
    private static final String METHOD_SUMMARY = "<!-- ========== METHOD SUMMARY =========== -->";
    private static final String FIELD_DETAILS = "<!-- ============ FIELD DETAIL =========== -->";
    private static final String METHOD_DETAILS = "<!-- ============ METHOD DETAIL ========== -->";
    private static final String CONST_DETAILS = "<!-- ========= CONSTRUCTOR DETAIL ======== -->";

    private static final String[] DETAIL_BEGIN =
    {
        CONST_DETAILS, METHOD_DETAILS, FIELD_DETAILS
    };

    private static final String[] DETAIL_ENDS =
    {
        CONST_DETAILS, METHOD_DETAILS, FIELD_DETAILS, "<HR>"
    };

    protected static boolean isDetailEnds(String line){
        for(String s : DETAIL_ENDS){
            if(line.startsWith(s))
                return true;
        }

        return false;
    }

    private static Pattern DETAIL_NAME_PATTERN = Pattern.compile("<A NAME=\"([^\"\\(]+)[^\"]*\"><!.*<H3>");
    protected static String getDetailName(String line){
        Matcher m = DETAIL_NAME_PATTERN.matcher(line);
        if(m.matches()){
            return m.group(1);
        }
        return null;
    }

    public static final String[] retPats = {
            "<p>",
            "</p>",
            "<br>",
            "<table[^>]*>",
            "</table>",
            "<tr[^>]>",
            "<td[^>]>",
            "<hr>"
        };
     public static final String[] hyperPats = {
            "<a [^>]*>([^<]+)</a>",
            "<code>([^<]+)</code>",
            "\\[+([^]]+)\\]+"
        };


     public static final String[] boldPats = {
            "<b>([^<]+)</b>"
     };

     public static final String[] removePats = {
            "<[^>]+>"
     };

     public DocHelper(String clazzName, String clazzFullName){
         this.clazzName = clazzName;
         this.clazzFullName = clazzFullName;
     }

     public void addLine(String line){
         switch(stage){
             case 0:
             {
                 for(String x : DETAIL_BEGIN){
                     if(line.startsWith(x)){
                         ++stage;
                         return;
                     }
                 }
                 clazzInfo.add(line);
                 return;
             }
             case 1: //detail
             {
                 String x = getDetailName(line);
                 if(x == null)
                     return;
                 currentDetailKey = x;
                 ++ stage;
                 return;
             }
             case 2:
             {
                 if(isDetailEnds(line)){
                     -- stage;
                     return;
                 }
                 List<String> list = detailInfo.get(currentDetailKey);
                 if(list == null)
                     list = new LinkedList<String>();
                 list.add(line);
                 detailInfo.put(currentDetailKey, list);
             }
         }
     }

     public static String parseToDictContent(List<String> list){
         StringBuilder sb = new StringBuilder();
         for(String s : list){
             sb.append(s).append("\n");
         }
         return parseToDictContent(sb.toString());
     }

    public static String parseToDictContent(String line) {
        for (String s : retPats) {
            Matcher m = Pattern.compile(s, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE).matcher(line);
            line = m.replaceAll("\n");
        }

        for (String s : hyperPats) {
            Matcher m = Pattern.compile(s, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE).matcher(line);
            line = m.replaceAll("[$1]");
        }

        for (String s : boldPats) {
            Matcher m = Pattern.compile(s, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE).matcher(line);
            line = m.replaceAll("[b]$1[/b]");
        }

        for (String s : removePats) {
            Matcher m = Pattern.compile(s, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE).matcher(line);
            line = m.replaceAll("");
        }

        //restore the bold
        {
            Matcher m = Pattern.compile("\\[b\\]([^\\[]+)\\[/b\\]", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE).matcher(line);
            line = m.replaceAll("<b>$1</b>");

            m = Pattern.compile("\\[b\\]", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE).matcher(line);
            line = m.replaceAll("");

            m = Pattern.compile("\\[/b\\]", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE).matcher(line);
            line = m.replaceAll("");
        }

        StringReader sr = new StringReader(line);
        BufferedReader br = new BufferedReader(sr);
        StringBuilder sb = new StringBuilder();
        try{
            String x;
            boolean lastReturn = false;
            while( ( x = br.readLine() )!=null){
                x = x.trim();
                if(x.length() == 0){
                    if(lastReturn)
                        continue;
                    lastReturn = true;
                    sb.append("\n");
                }
                else
                {
                    lastReturn = false;
                    sb.append(x).append("\n");
                }
            }
        }catch(IOException ioe){

        }
        return sb.toString();
    }

    public List<String> getClazzInfo() {
        return clazzInfo;
    }

    public Map<String, List<String>> getDetailInfo() {
        return detailInfo;
    }

    public String getClazzFullName() {
        return clazzFullName;
    }

    public String getClazzName() {
        return clazzName;
    }

    
}
